from django.db import models, IntegrityError
from flexy.common.errors import *
from django.contrib.auth.models import *

SUPPORTED_FIELD_TYPES = ["INT", "FLOAT", "CHAR", "CHAR_UNIQ", 
    "TEXT", "NTO1", "DATE", "TIME", "NTOM", "IMAGES", "FILES"]

NTO_SUPPORTED_FIELD_TYPES = ["FLOAT", "CHAR", "DATE"]

class FlexyClassManager(models.Manager):
    def add(self, name, enb) :
        name = ' '.join(name.upper().split())
        if name == '' :
            #Empty name
            return err[1][1]
        if enb == '1' or enb == '0' :
            pass
        else :
            #Invalid value for enabled
            return err[1][2]
        flexyClass = self.model(name=name, enb=int(enb))
        try :
            flexyClass.save()
        except IntegrityError :
            #already exists
            return err[1][3]
        return err[1][0]

class FlexyClass(models.Model):
    name = models.CharField(max_length=255, unique=True, null=False)
    enb = models.BooleanField()
    objects = FlexyClassManager()
    usergroup_perm = models.ManyToManyField(Group, through='UserGroup_FlexyClass')

class GroupManager(models.Manager):
    def add(self, name, class_id) :
        name = ' '.join(name.upper().split())
        if name == '' :
            #Empty name
            return err[2][1]
        
        flexyclass = FlexyClass.objects.get(id=class_id)
        if flexyclass.enb == 0 :
            #Class not enabled
            return err[2][4]
        
        group = self.model(name=name, seq=0, 
            flexyclass=flexyclass)
        try :
            group.save()
        except IntegrityError :
            #already exists
            return err[2][3]
        return err[2][0]

class FlexyGroup(models.Model):
    flexyclass = models.ForeignKey(FlexyClass)
    name = models.CharField(max_length=255, null=False)
    seq = models.IntegerField()
    objects = GroupManager()
    
    class Meta:
        unique_together = (('flexyclass', 'name'),)
        
class FieldManager(models.Manager):
    def add(self, name, type, group_id, enb, sel_field_id) :
        name = ' '.join(name.upper().split())
        if name == '' :
            #Empty name
            return err[3][1]
        
        if enb == '1' or enb == '0' :
            pass
        else :
            #Invalid value for enabled
            return err[3][3]
        
        if type not in SUPPORTED_FIELD_TYPES :
            #Invalid Field type provided
            return err[3][4]
        
        group = FlexyGroup.objects.get(id=group_id)
        if group.flexyclass.enb == 0 :
            #Class not enabled
            return err[3][5]
        
        sel_field = None
        if type == 'NTO1' or type == 'NTOM' :
            sel_field = Field.objects.get(id=int(sel_field_id))
            if sel_field.enb == False :
                return err[3][7]
            if sel_field.type != 'CHAR_UNIQ' :
                return err[3][8]

        prtn_id = Field.objects.filter(type=type).count()
        field = self.model(flexyclass = group.flexyclass, group = group,
            name = name, type = type, seq = 0, enb = enb, 
            sel_field = sel_field, prtn_id = prtn_id,
            extra_field_parent = None)

        try :
            field.save()
        except IntegrityError :
            #already exists
            return err[3][6]
        return err[3][0]
    
    def extra_field_add(self, name, type, enb, parent_field) :
        name = ' '.join(name.upper().split())
        if name == '' :
            #Empty name
            return err[8][1]
        if enb == '1' or enb == '0' :
            pass
        else :
            #Invalid value for enabled
            return err[8][3]
        if type not in NTO_SUPPORTED_FIELD_TYPES :
            #Invalid Field type provided
            return err[8][4]
        
        prtn_id = Field.objects.filter(type=type).exclude(extra_field_parent=None).count()
        field = self.model(flexyclass = parent_field.group.flexyclass, 
            group = parent_field.group, name = name, type = type, seq = 0, 
            enb = enb, sel_field = None, prtn_id = prtn_id,
            extra_field_parent = parent_field)
        
        try :
            field.save()
        except IntegrityError :
            #already exists
            return err[8][2]
        return err[8][0]


class Field(models.Model):
    flexyclass = models.ForeignKey(FlexyClass)
    group = models.ForeignKey(FlexyGroup)
    name = models.CharField(max_length=255, null=False)
    type = models.CharField(max_length=64, null=False)
    seq = models.IntegerField()
    enb = models.BooleanField()
    prtn_id = models.IntegerField()
    objects = FieldManager()
    sel_field = models.ForeignKey('self', null=True, 
        related_name="%(app_label)s_%(class)s_sel_field")
    extra_field_parent = models.ForeignKey('self', null=True,
        related_name="%(app_label)s_%(class)s_extra_field_parent")
    display_fields = models.ManyToManyField('self', symmetrical=False)
    usergroup_perm = models.ManyToManyField(Group, through='UserGroup_Field')
    
    class Meta:
        unique_together = (('flexyclass', 'name'),)

class UserGroup_FlexyClassManager(models.Manager):
    def set_perm(self, ug, class_id, perm) :
        flexyclass = FlexyClass.objects.get(id = class_id)
        ugc, created = UserGroup_FlexyClass.objects.get_or_create \
            (flexyclass = flexyclass, usergroup = ug)
        ugc.perm = perm
        ugc.save()

class UserGroup_FlexyClass(models.Model):
    flexyclass = models.ForeignKey(FlexyClass)
    usergroup = models.ForeignKey(Group)
    perm = models.IntegerField(null=True)
    objects = UserGroup_FlexyClassManager()
    class Meta:
        unique_together = (('flexyclass', 'usergroup'),)

class UserGroup_FieldManager(models.Manager):
    def set_perm(self, ug, field_id, perm) :
        field = Field.objects.get(id = field_id)
        ugf, created = UserGroup_Field.objects.get_or_create \
            (field = field, usergroup = ug)
        ugf.perm = perm
        ugf.save()

class UserGroup_Field(models.Model):
    field = models.ForeignKey(Field)
    usergroup = models.ForeignKey(Group)
    perm = models.IntegerField(null=True)
    objects = UserGroup_FieldManager()
    class Meta:
        unique_together = (('field', 'usergroup'),)

